home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Best of Shareware
/
Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso
/
mac
/
ZIPPED
/
DOS
/
GRAPHICS
/
LISS151.ZIP
/
LISSSRC.ZIP
/
OUTPUT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-21
|
37KB
|
1,079 lines
/* ***********************
OUTPUT.C
This program displays spherical Lissajous figures and writes a
data file in either Vivid, Persistence of Vision (PoV), or Connect
the Dots Smoother (CTDS) format. It also outputs a 'raw' format
with just the (x,y,z) of each point.
Program originally written by Dan Farmer using algorithms from
Clifford Pickover. Converted from QuickBasic to C by Aaron C. Caba.
See Scientific American January 1991 and Omni February 1990 for
excellent examples by Pickover.
History:
Version 1.51:
04/14/92 ACC Adjust camera positioning so it is WYSIWYG with the display
04/06/92 ACC Incorporate Dan's PoV V. 1.0 syntax and test it.
Put statistics output into a separate function
04/03/92 DMF Changed PoV output for version 1.0 syntax. (Untested.)
Version 1.5:
03/10/92 ACC Do some cosmetic fixes
03/09/92 ACC found bug in sort_index: changed *count++ to (*count)++
Version 1.4:
02/11/92 ACC Actually get algo_period to spit out the correct
answer, now ctds_sort works
01/13/92 ACC Finish algo_period (and there was much rejoycing) (Yeah!)
01/12/92 ACC Add 'smooth' Vivid output
01/07/92 ACC Change all scatered calls to 'exit()' to error_fn.
01/06/92 ACC Add raw output.
12/21/91 ACC Write these _beautiful_ output functions.
*************************/
#include "output.h" /* function prototypes */
#ifdef DEBUG
unsigned long debug;
#endif
/* Procedure to choose which output format is desired */
void output(struct queue_type queue[], int index[], int num_sph, char *data[])
{
char ch;
int ch_ok=FALSE;
setactivepage(1); /* save page #0 so it dosen't have to be re-drawn */
setvisualpage(1); /* choose page #1 to draw on */
clearviewport();
disp_text(5,0,"Script file type: [P]oV [V]ivid [C]TDS [R]aw",EGA_DARKGRAY);
disp_message("Press <ESC> to cancel");
while (!ch_ok) {
ch=getch();
ch_ok=TRUE;
switch(ch) {
case 'p':
case 'P':
choose_pv_output(queue, index, num_sph, data);
break;
case 'v':
case 'V':
choose_v_output(queue, index, num_sph, data);
break;
case 'c':
case 'C':
ctds_output(queue, num_sph, data);
break;
case 'r':
case 'R':
raw_output(queue, index, num_sph, data);
break;
case ESC:
case RETURN: break;
default:
ch_ok=FALSE;
break;
}
}
setactivepage(0); /* return to gui-like screen */
setvisualpage(0);
}
void choose_pv_output(struct queue_type queue[], int index[],
int num_sph, char *data[])
{
int ch_ok=FALSE;
char ch;
disp_text(8,1,"PoV file type: Version [0].5ß Version [1].0 ",EGA_DARKGRAY);
while (!ch_ok) {
ch=getch();
ch_ok=TRUE;
switch(ch) {
case '0':
pv_output(queue, index, num_sph, data, POV_VER_05);
break;
case '1':
pv_output(queue, index, num_sph, data, POV_VER_10);
case RETURN:
case ESC:
break;
default:
ch_ok=FALSE;
break;
}
}
} /* end choose_pv_output */
void choose_v_output(struct queue_type queue[], int index[],
int num_sph, char *data[])
{
int ch_ok=FALSE;
char ch;
disp_text(8,1,"Vivid file type: [S]mooth [B]eaded",EGA_DARKGRAY);
while (!ch_ok) {
ch=getch();
ch_ok=TRUE;
switch(ch) {
case 's':
case 'S':
smooth_v_output(queue, index, num_sph, data);
break;
case 'b':
case 'B':
v_output(queue, index, num_sph, data);
case RETURN:
case ESC:
break;
default:
ch_ok=FALSE;
break;
}
}
} /* end choose_v_output */
void raw_output(struct queue_type queue[], int index[],
int num_sph, char *data[])
{
int ch_ok=FALSE;
char ch;
disp_text(8,1,"Sort data on: View-[A]xis or [C]TDS sytle",EGA_DARKGRAY);
while (!ch_ok) {
ch=getch();
ch_ok=TRUE;
switch(ch) {
case 'a':
case 'A':
write_raw_spheres(queue, index, num_sph);
break;
case 'c':
case 'C':
write_craw_spheres(queue, num_sph, data);
case RETURN:
case ESC:
break;
default:
ch_ok=FALSE;
break;
}
}
} /* end raw_output */
void write_raw_spheres(struct queue_type queue[], int index[], int num_sph)
{
int i;
char name[13], /* name of file to write to */
msg[80];
FILE *stream; /* file pointer to 'name' */
/* have user input the name of the data file to use */
strcpy(name,input_name(".RAW"));
if (strlen(name) == 0) return; /* bail out back to main menu */
/* open the data file */
if((stream=fopen(name,"wt")) == NULL)
error_fn(EFOPEN,name);
else {
/* write the data */
sprintf(msg,"Writing %s...",name);
disp_message(msg);
for(i=0; i<num_sph; i++)
fprintf(stream,"%11f %11f %11f\n",
queue[index[i]].x,queue[index[i]].y,queue[index[i]].z);
/* close the file */
if(fclose(stream)==EOF)
error_fn(EFCLOSE,name);
else {
sprintf(msg,"RAW data file %s sucessfully written. Any key to continue:",name);
disp_message(msg);
getch();
}
}
} /* end write_raw_spheres */
void write_craw_spheres(struct queue_type queue[], int num_sph, char *data[])
{
struct pnode far *root=NULL;
char name[13], /* name of data file */
msg[80]; /* temp string */
FILE *stream; /* the file handel */
/* have user input the name of the data file to use */
strcpy(name,input_name(".RAW"));
if (strlen(name) == 0) return; /* bail out back to main menu */
root=ctds_sort(root, num_sph, algo_period(data));
/* open the data file */
if((stream=fopen(name,"wt")) == NULL)
error_fn(EFOPEN,name);
else {
/* write the data */
sprintf(msg,"Writing %s...",name);
disp_message(msg);
ftreeprint(stream, queue, root, 0, NULL);
/* close the file */
if(fclose(stream)==EOF)
error_fn(EFCLOSE,name);
else {
sprintf(msg,"RAW data file %s sucessfully written. Any key to continue:",name);
disp_message(msg);
getch();
}
}
free_tree(root);
} /* end write_craw_spheres */
/* This function determines the period of the algorithm
based on the a,b, and exponent variables. */
double algo_period(char *data[])
{
double per,
x_per,y_per,z_per, /* in units of PI */
a,b,
temp;
int exp_x, exp_y, exp_z;
disp_message("Finding period...");
exp_x=atoi(data[EXPONENT_X]);
exp_y=atoi(data[EXPONENT_Y]);
exp_z=atoi(data[EXPONENT_Z]);
a=atof(data[A]);
b=atof(data[B]);
per=gcd(a,b);
switch(atoi(data[ALGO])) {
case 1:
case 2:
case 3:
x_per=y_per=PI;
if(even(exp_z)) z_per=PI;
else z_per=2.0*PI;
x_per = PI/per;
y_per = PI/per;
z_per /= a;
break;
case 4:
if(even(exp_x)) x_per=PI/2.0;
else x_per=PI;
if(even(exp_y)) y_per=PI;
else y_per=2.0*PI;
if(even(exp_z)) z_per=PI;
else z_per=2.0*PI;
z_per /= a;
break;
case 5:
if (even(exp_x)) x_per=2.0*PI/a;
else x_per=PI/a;
if (even(exp_y)) y_per=2.0*PI/b;
else y_per=PI/b;
if (even(exp_z)) z_per=PI;
else z_per=2*PI;
break;
}
temp=lcm(x_per,y_per,z_per);
return(2*temp);
} /* end algo_period */
double lcm(double x, double y, double z)
{
double val;
val=x*y/gcd(x,y);
return(val*z/gcd(val,z));
}
double gcd(double a, double b)
{
while (!equal(a,b)) {
if (a < b)
b -= a;
else a -= b;
}
return(a);
}
void ctds_output(struct queue_type queue[], const int num_sph, char *data[])
{
struct pnode far *root=NULL;
char name[13], /* name of data file */
msg[80]; /* temp string */
FILE *stream; /* the file handel */
struct max_vals val; /* to track the highest and lowest x,y, and z coord */
/* init some vars */
strcpy(name,""); /* clear strings */
val.xl=val.xh=queue[0].x; /* init high/low trackers */
val.yl=val.yh=queue[0].y;
val.zl=val.zh=queue[0].z;
/* have user input the name of the data file to use */
strcpy(name,input_name(".CTD"));
if (strlen(name) == 0) return; /* bail out back to main menu */
root=ctds_sort(root, num_sph, algo_period(data));
/* open the data file */
if((stream=fopen(name,"wt")) == NULL)
error_fn(EFOPEN,name);
else {
/* write the data */
sprintf(msg,"Writing %s...",name);
disp_message(msg);
write_ctds_header(stream, name);
ftreeprint(stream, queue, root, atoi(data[SPH_RADIUS]), &val);
write_ctds_footer(stream, name, data, val);
if(fclose(stream)==EOF)
error_fn(EFCLOSE,name);
else {
sprintf(msg,"CTDS data file %s sucessfully written. Any key to continue:",name);
disp_message(msg);
getch();
}
}
free_tree(root);
} /* end ctds_output */
struct pnode far *ctds_sort(struct pnode far *root, int num_sph, double period)
{
int i;
double i_per;
disp_message("Sorting data...");
for (i=0; i<num_sph; i++) {
i_per=(i/period)-floor(i/period);
root=tree(root, i, i_per);
}
return(root);
}
struct pnode far *tree(struct pnode far *p, int i, double i_per)
{
char msg[40];
static unsigned long treecount;
if (p==NULL) { /* new number */
if ((p = palloc()) == NULL) { /* make a new node */
sprintf(msg,"tree calls: %u",treecount);
error_fn(EMEM,msg);
}
else treecount++;
p->n=i;
p->t=i_per;
p->left = p->right = NULL;
}
else if (i_per < p->t) /* if (i_per == p->t), then do nothing */
p->left=tree(p->left, i, i_per); /* because it is a repeated point */
else if (i_per > p->t)
p->right=tree(p->right, i, i_per);
return(p);
}
/* free up the memmroy used by the binary tree */
void free_tree(struct pnode far *p)
{
if (p->left != NULL)
free_tree(p->left);
if (p->right != NULL)
free_tree(p->right);
free(p);
}
struct pnode far *palloc(void)
{
#ifdef DEBUG
char msg[40];
debug=farcoreleft();
sprintf(msg,"free far core: %lu",debug);
disp_message(msg);
#endif
return((struct pnode far *) farmalloc(sizeof(struct pnode)));
}
/* either for CTDS output or CTDS sorted RAW output. */
void ftreeprint(FILE *stream, struct queue_type queue[],
struct pnode far *p, int r, struct max_vals *val)
{
float x,y,z;
if (p != NULL) {
ftreeprint(stream, queue, p->left, r, val);
x=queue[p->n].x;
y=queue[p->n].y;
z=queue[p->n].z;
if (r == 0) { /* for raw mode */
fprintf(stream,"%11f %11f %11f\n",x,y,z);
}
else {
/* keep track of lowest and highest values */
if (x < val->xl) val->xl=x;
if (y < val->yl) val->yl=y;
if (z < val->zl) val->zl=z;
if (x > val->xh) val->xh=x;
if (y > val->yh) val->yh=y;
if (z > val->zh) val->zh=z;
fprintf(stream,"%10f %10f %10f %2i\n",x,y,z,r);
}
ftreeprint(stream, queue, p->right, r, val);
}
} /* end ftreeprint */
/* sort the array 'index' to the order in the binary tree 'p' */
void sort_index(struct queue_type queue[], int index[],
struct pnode far *p, int *count)
{
if (p!=NULL) {
sort_index(queue, index, p->left, count);
index[(*count)++]=(p->n);
sort_index(queue, index, p->right, count);
}
}
void v_output(struct queue_type queue[], int index[], int num_sph, char *data[])
{
char name[13], /* name of data file */
numcolors[3], /* number of colors to use */
msg[80]; /* temp string */
FILE *stream; /* the file handel */
struct max_vals val; /* to track the highest and lowest x,y, and z coord */
/* init some vars */
strcpy(name,""); /* clear strings */
strcpy(numcolors,"");
val.xl=val.xh=queue[0].x; /* init high/low trackers */
val.yl=val.yh=queue[0].y;
val.zl=val.zh=queue[0].z;
/* have user input the name of the data file to use */
strcpy(name,input_name(".V"));
if (strlen(name) == 0) return; /* bail out back to main menu */
/* now write out the data file */
if((stream=fopen(name,"wt")) == NULL)
error_fn(EFOPEN,name);
else {
sprintf(msg,"Writing %s...",name);
disp_message(msg);
write_v_header(stream, name, data[AXIS]);
write_v_spheres(stream, queue, index,
atoi(data[SPH_RADIUS]), num_sph, &val);
write_v_footer(stream, name, data, val);
if(fclose(stream)==EOF)
error_fn(EFCLOSE,name);
else {
sprintf(msg,"Vivid data file %s sucessfully written. Any key to continue:",name);
disp_message(msg);
getch();
}
}
} /* end v_output */
void smooth_v_output(struct queue_type queue[], int index[],
int num_sph, char *data[])
{
int count=0;
char name[13], /* name of data file */
msg[80]; /* temp string */
FILE *stream; /* the file handel */
struct pnode far *root=NULL; /* pointer to sorted spheres */
struct max_vals val; /* to track the highest and lowest x,y, and z coord */
/* init some vars */
strcpy(name,""); /* clear strings */
val.xl=val.xh=queue[0].x; /* init high/low trackers */
val.yl=val.yh=queue[0].y;
val.zl=val.zh=queue[0].z;
/* have user input the name of the data file to use */
strcpy(name,input_name(".V"));
if (strlen(name) == 0) return; /* bail out back to main menu */
root=ctds_sort(root, num_sph, algo_period(data));
/* now write out the data file */
if((stream=fopen(name,"wt")) == NULL)
error_fn(EFOPEN,name);
else {
sprintf(msg,"Writing %s...",name);
disp_message(msg);
write_v_header(stream, name, data[AXIS]);
sort_index(queue, index, root, &count);
write_smooth_v_spheres(stream, queue, index,
atoi(data[SPH_RADIUS]), num_sph, &val);
write_v_footer(stream, name, data, val);
if(fclose(stream)==EOF)
error_fn(EFCLOSE,name);
else {
sprintf(msg,"Vivid data file %s sucessfully written. Any key to continue:",name);
disp_message(msg);
getch();
}
}
free_tree(root);
} /* end smooth_v_output */
void write_smooth_v_spheres(FILE *stream, struct queue_type queue[], int index[],
int radius, int num_sph, struct max_vals *val)
{
int i,k;
float x, y, z,
x1, y1, z1;
/* write one sphere and one connecting cylinder */
for (i=0; i<num_sph; i++) {
x=queue[index[i]].x;
y=queue[index[i]].y;
z=queue[index[i]].z;
k=i+1;
if (k >= num_sph) k=0;
x1=queue[index[k]].x;
y1=queue[index[k]].y;
z1=queue[index[k]].z;
/* keep track of lowest and highest values */
if (x < val->xl) val->xl=x;
if (y < val->yl) val->yl=y;
if (z < val->zl) val->zl=z;
if (x > val->xh) val->xh=x;
if (y > val->yh) val->yh=y;
if (z > val->zh) val->zh=z;
/* print a sphere and connector */
fprintf(stream,"sphere = { center = %f %f %f; radius = %i; }\n",x,y,z,radius);
fprintf(stream,"cone = { base = %f %f %f; base_radius = %i;\n",x,y,z,radius);
fprintf(stream," apex = %f %f %f; apex_radius = %i; }\n",x1,y1,z1,radius);
}
} /* end write_smooth_v_spheres */
void write_v_spheres(FILE *stream, struct queue_type queue[], int index[],
int radius, int num_sph, struct max_vals *val)
{
int i;
float x,y,z;
/* write one sphere at a time */
for (i=0; i<num_sph; i++) {
x=queue[index[i]].x;
y=queue[index[i]].y;
z=queue[index[i]].z;
/* keep track of lowest and highest values */
if (x < val->xl) val->xl=x;
if (y < val->yl) val->yl=y;
if (z < val->zl) val->zl=z;
if (x > val->xh) val->xh=x;
if (y > val->yh) val->yh=y;
if (z > val->zh) val->zh=z;
/* print a sphere */
fprintf(stream,"sphere = { center = %f %f %f; radius = %i; }\n",x,y,z,radius);
}
}
void pv_output(struct queue_type queue[], int index[],
int num_sph, char *data[], int version)
{
int col, /* number of colors to be inputed */
actualcolors=0, /* number of colors actually inputed by user */
i; /* scratch loop variable */
char name[13], /* name of data file */
numcolors[3], /* number of colors to use */
*output_color[MAX_OUTPUT_COLORS], /* string of color definition */
msg[80]; /* temp string */
FILE *stream; /* the file handel */
struct max_vals val; /* to track the highest and lowest x,y, and z coord */
extern struct field_struct field[];
/* init some vars */
strcpy(name,""); /* clear strings */
strcpy(numcolors,"");
val.xl=val.xh=queue[0].x; /* init high/low trackers */
val.yl=val.yh=queue[0].y;
val.zl=val.zh=queue[0].z;
parm_field=FALSE;
/* allocate space for user inputed color definitions */
for(i=0; i<MAX_OUTPUT_COLORS; i++) {
if ((output_color[i]=malloc(sizeof(char)*OUTPUT_COLOR_LEN)) == NULL)
error_fn(EMEM,"pv05_output");
strcpy(output_color[i],"");
}
/* have user input the name of the data file to use */
if (version == POV_VER_10)
strcpy(name,input_name(".POV"));
else strcpy(name,input_name(".DAT"));
if (strlen(name) == 0) return; /* bail out back to main menu */
/* input the number of colors to use and assign numercal value to 'col' */
erase_text(9,field[FILE_NAME].y,38);
sprintf(msg,"How may colors would you like to use? (MAX=%i) ",MAX_OUTPUT_COLORS);
disp_text(8,field[NUMCOLORS].y,msg,EGA_DARKGRAY);
fieldinput(NUMCOLORS,numcolors,"Press <ESC> to cancel",0);
col=atoi(numcolors);
if (col==0) return;
if (col > MAX_OUTPUT_COLORS) col=MAX_OUTPUT_COLORS;
/* now input all the colors... */
for(i=0; i<col; i++) {
sprintf(msg,"declare Color%i = color ",i);
disp_text(8,field[COLOR_NAME].y+i,msg,EGA_DARKGRAY);
fieldinput(COLOR_NAME,output_color[i],"Press <ESC> to cancel",i);
if (!strcmp(output_color[i],"")) break;
actualcolors++;
}
if (actualcolors==0) { /* a little error traping */
actualcolors=1;
strcpy(output_color[0],"CRed");
}
/* now write out the data file in 'version' format */
if((stream=fopen(name,"wt")) == NULL)
error_fn(EFOPEN,name);
else {
sprintf(msg,"Writing %s ...",name);
disp_message(msg);
if (version==POV_VER_05) {
write_pv05_header(stream, name, actualcolors,
output_color, atoi(data[SPH_RADIUS]), data[AXIS]);
write_pv05_spheres(stream, queue, index,
actualcolors, num_sph, &val);
write_pv05_footer(stream, name, data, val);
}
else {
write_pv10_header(stream, name, actualcolors,
output_color, atoi(data[SPH_RADIUS]), data[AXIS]);
write_pv10_spheres(stream, queue, index,
actualcolors, num_sph, &val);
write_pv10_footer(stream, name, data, val);
}
if(fclose(stream)==EOF)
error_fn(EFCLOSE,name);
else {
sprintf(msg,"PoV data file %s sucessfully written. Any key to continue:",name);
disp_message(msg);
getch();
}
}
/* do a little memmory clean-up */
for(i=0; i<MAX_OUTPUT_COLORS; i++) free(output_color[i]);
} /* end pv05_output */
void write_pv05_header(FILE *stream, char *name, int actualcolors,
char *output_color[], int radius, char *axis)
{
int i;
struct tm *tblock;
time_t timer;
char time_str[80];
/* get the current time and date, so it can be put into data file */
timer = time(NULL);
tblock = localtime(&timer);
strcpy(time_str,asctime(tblock));
/* Hit it! */
fprintf(stream,"{\n");
fprintf(stream," Lissajous figure PoV Ver. 0.5ß datafile %s\n", name);
fprintf(stream," Generated on %s with LISSAJOU V %s\n",time_str,VERSION);
fprintf(stream," by Aaron C. Caba and Dan Farmer\n");
fprintf(stream,"}\n");
fprintf(stream,"\n");
fprintf(stream,"include \"shapes.dat\"\n");
fprintf(stream,"include \"colors.dat\"\n");
fprintf(stream,"include \"textures.dat\"\n");
fprintf(stream,"\n");
fprintf(stream,"declare Atexture = texture\n");
fprintf(stream," ambient 0.1 { same as textures.dat SHINY texture}\n");
fprintf(stream," diffuse 0.9\n");
fprintf(stream," phong 1.0\n");
fprintf(stream," phongsize 30.0\n");
fprintf(stream,"end_texture\n");
fprintf(stream,"\n");
fprintf(stream,"declare Sph_Radius = %i\n",radius);
fprintf(stream,"\n");
fprintf(stream,"view_point\n");
switch (axis[0]) {
case 'X':
fprintf(stream," location <350.0 0.0 0.0> {modify as needed}\n");
fprintf(stream," direction < -1.0 0.0 0.0>\n");
fprintf(stream," up < 0.0 0.0 1.0>\n");
fprintf(stream," right < 0.0 1.3333 0.0> /* right-handed! */\n");
break;
case 'Y':
fprintf(stream," location <0.0 350.0 0.0> {modify as needed}\n");
fprintf(stream," direction <0.0 -1.0 0.0>\n");
fprintf(stream," up <1.0 0.0 0.0>\n");
fprintf(stream," right <0.0 0.0 1.3333> /* right-handed! */\n");
break;
case 'Z':
fprintf(stream," location <0.0 0.0 350.0> {modify as needed}\n");
fprintf(stream," direction <0.0 0.0 -1.0>\n");
fprintf(stream," up <0.0 1.0 0.0>\n");
fprintf(stream," right <1.3333 0.0 0.0> /* right-handed! */\n");
break;
}
fprintf(stream," look_at <0.0 0.0 0.0>\n");
fprintf(stream,"end_view_point\n");
fprintf(stream,"\n");
fprintf(stream,"{ basic light source }\n");
fprintf(stream,"object\n");
fprintf(stream," sphere <0.0 0.0 0.0> 2.0 end_sphere\n");
fprintf(stream," translate <300.0 300.0 300.0>\n");
fprintf(stream," colour red 1.0 green 1.0 blue 1.0\n");
fprintf(stream," light_source\n");
fprintf(stream," texture\n");
fprintf(stream," ambient 1.0\n");
fprintf(stream," diffuse 0.0\n");
fprintf(stream," color red 1.0 green 1.0 blue 1.0\n");
fprintf(stream," end_texture\n");
fprintf(stream,"end_object\n");
fprintf(stream,"\n");
fprintf(stream,"{ Put all colors into declarations for ease of changing }\n\n");
/* print the user inputed color definitions */
for(i=0; i<actualcolors; i++) {
fprintf(stream,"declare Color%i = color %s\n",i,output_color[i]);
}
fprintf(stream,"\n");
fprintf(stream,"{ Here it is... }\n\n");
fprintf(stream,"composite\n\n");
}
void write_pv05_spheres(FILE *stream, struct queue_type queue[], int index[],
int actualcolors, int num_sph, struct max_vals *val)
{
int i;
float x,y,z;
/* write one sphere at a time */
for (i=0; i<num_sph; i++) {
x=queue[index[i]].x;
y=queue[index[i]].y;
z=queue[index[i]].z;
/* keep track of lowest and highest values */
if (x < val->xl) val->xl=x;
if (y < val->yl) val->yl=y;
if (z < val->zl) val->zl=z;
if (x > val->xh) val->xh=x;
if (y > val->yh) val->yh=y;
if (z > val->zh) val->zh=z;
fprintf(stream," object\n");
fprintf(stream," sphere <%f %f %f> Sph_Radius end_sphere\n",x,y,z);
fprintf(stream," color Color%i\n", i%actualcolors);
fprintf(stream," texture\n");
fprintf(stream," Atexture\n");
fprintf(stream," color Color%i\n", i%actualcolors);
fprintf(stream," end_texture\n");
fprintf(stream," end_object\n");
/* a kludge to fix PoV V0.5ß's problem with large size composites */
if ((i+1 % 25) == 0) {
fprintf(stream,"end_composite\n");
fprintf(stream,"composite\n");
}
}
}
void write_pv05_footer(FILE *stream, char *name,
char *data[], struct max_vals val)
{
fprintf(stream,"\n");
fprintf(stream,"end_composite\n");
fprintf(stream,"{\n");
write_stats(stream, "", data, val, atof(data[SPH_RADIUS]));
fprintf(stream,"}\n");
fprintf(stream,"{ *** End of %s *** }\n",name);
}
void write_pv10_header(FILE *stream, char *name, int actualcolors,
char *output_color[], int radius, char *axis)
{
int i;
struct tm *tblock;
time_t timer;
char time_str[80];
/* get the current time and date, so it can be put into data file */
timer = time(NULL);
tblock = localtime(&timer);
strcpy(time_str,asctime(tblock));
/* Hit it! */
fprintf(stream,"/*\n");
fprintf(stream," Lissajous figure PoV Ver. 1.0 datafile %s\n", name);
fprintf(stream," Generated on %s with LISSAJOU V %s\n",time_str,VERSION);
fprintf(stream," by Aaron C. Caba and Dan Farmer\n");
fprintf(stream,"*/\n\n");
fprintf(stream,"#include \"shapes.inc\"\n");
fprintf(stream,"#include \"colors.inc\"\n");
fprintf(stream,"#include \"textures.inc\"\n\n");
fprintf(stream,"#declare Atexture = texture {\n");
fprintf(stream," ambient 0.1 \n");
fprintf(stream," diffuse 0.8\n");
fprintf(stream," phong 1.0\n");
fprintf(stream," phong_size 30.0\n");
fprintf(stream,"}\n\n");
fprintf(stream,"#declare Sph_Radius = %i\n\n",radius);
fprintf(stream,"camera { // modify as needed -- note right handed coords!\n");
switch (axis[0]) {
case 'X':
fprintf(stream," location <350.0 0.0 0.0>\n");
fprintf(stream," direction < -1.0 0.0 0.0>\n");
fprintf(stream," up < 0.0 0.0 1.0>\n");
fprintf(stream," right < 0.0 1.3333 0.0>\n");
break;
case 'Y':
fprintf(stream," location <0.0 350.0 0.0>\n");
fprintf(stream," direction <0.0 -1.0 0.0>\n");
fprintf(stream," up <1.0 0.0 0.0>\n");
fprintf(stream," right <0.0 0.0 1.3333>\n");
break;
case 'Z':
fprintf(stream," location <0.0 0.0 350.0>\n");
fprintf(stream," direction <0.0 0.0 -1.0>\n");
fprintf(stream," up <0.0 1.0 0.0>\n");
fprintf(stream," right <1.3333 0.0 0.0>\n");
break;
}
fprintf(stream," look_at <0.0 0.0 0.0>\n");
fprintf(stream,"}\n\n");
fprintf(stream,"// basic light source \n");
fprintf(stream,"object { light_source { <300 300 300> color White} }\n");
fprintf(stream,"\n");
fprintf(stream,"// Put all colors into declarations for ease of changing \n");
fprintf(stream,"\n");
/* print the user inputed color definitions */
for(i=0; i<actualcolors; i++) {
fprintf(stream,"#declare Color%i = color %s\n",i,output_color[i]);
}
fprintf(stream,"\n");
fprintf(stream,"// Here it is... \n\n");
fprintf(stream,"composite {\n\n");
} /* end write_pv10_header */
void write_pv10_spheres(FILE *stream, struct queue_type queue[], int index[],
int actualcolors, int num_sph, struct max_vals *val)
{
int i;
float x,y,z;
/* write one sphere at a time */
for (i=0; i<num_sph; i++) {
x=queue[index[i]].x;
y=queue[index[i]].y;
z=queue[index[i]].z;
/* keep track of lowest and highest values */
if (x < val->xl) val->xl=x;
if (y < val->yl) val->yl=y;
if (z < val->zl) val->zl=z;
if (x > val->xh) val->xh=x;
if (y > val->yh) val->yh=y;
if (z > val->zh) val->zh=z;
fprintf(stream," object {\n");
fprintf(stream," sphere { <%f %f %f> Sph_Radius }\n",x,y,z);
fprintf(stream," color Color%i\n", i%actualcolors);
fprintf(stream," texture {\n");
fprintf(stream," Atexture\n");
fprintf(stream," color Color%i\n", i%actualcolors);
fprintf(stream," }\n"); /* end texture block */
fprintf(stream," }\n"); /* end object block */
}
} /* end write_pv10_spheres */
void write_pv10_footer(FILE *stream, char *name,
char *data[], struct max_vals val)
{
fprintf(stream,"} // end composite\n"); /* end composite */
fprintf(stream,"\n");
fprintf(stream,"/*\n");
write_stats(stream, "", data, val, atof(data[SPH_RADIUS]));
fprintf(stream,"*/\n");
fprintf(stream,"// *** End of %s *** \n",name);
} /* end write_pv10_footer */
void write_v_header(FILE *stream, char *name, char *axis)
{
struct tm *tblock;
time_t timer;
char time_str[80];
timer = time(NULL);
tblock = localtime(&timer);
strcpy(time_str,asctime(tblock));
fprintf(stream,"/*\n");
fprintf(stream," Lissajous figure Vivid datafile %s\n", name);
fprintf(stream," Generated on %s with LISSAJOU V %s\n", time_str,VERSION);
fprintf(stream," by Aaron C. Caba and Dan Farmer\n");
fprintf(stream,"*/\n");
fprintf(stream,"\n");
fprintf(stream,"studio = {\n");
switch (axis[0]) {
case 'X':
fprintf(stream," from = 500.0 0.0 0.0;\n");
fprintf(stream," up = 0.0 0.0 1.0;\n");
break;
case 'Y':
fprintf(stream," from = 0.0 500.0 0.0;\n");
fprintf(stream," up = 1.0 0.0 0.0;\n");
break;
case 'Z':
fprintf(stream," from = 0.0 0.0 500.0;\n");
fprintf(stream," up = 0.0 1.0 0.0;\n");
break;
}
fprintf(stream," at = 0.0 0.0 0.0;\n");
fprintf(stream," angle = 35;\n");
fprintf(stream," resolution = 320 200;\n");
fprintf(stream," aspect = 1.3333;\n");
/* fprintf(stream," bkg = black;\n"); */
fprintf(stream," ambient = .1 .1 .1;\n");
fprintf(stream,"}\n");
fprintf(stream,"\n");
fprintf(stream,"light = {\n");
fprintf(stream," type = point;\n");
fprintf(stream," falloff = 1;\n");
fprintf(stream," position = 300.0 300.0 300.0;\n");
fprintf(stream," color = 300 300 300;\n");
fprintf(stream,"}\n");
fprintf(stream,"\n");
fprintf(stream,"surface = {\n");
fprintf(stream," diffuse = 0.8 0.3 0.3;\n");
fprintf(stream," ambient = 0.1 0.1 0.1;\n");
fprintf(stream," shine = 50 0.5 0.5 0.5;\n");
fprintf(stream,"}\n");
fprintf(stream,"\n");
} /* end write_v_header */
void write_v_footer(FILE *stream, char *name, char *data[],
struct max_vals val)
{
fprintf(stream,"\n");
fprintf(stream,"/*\n");
write_stats(stream, "", data, val, atof(data[SPH_RADIUS]));
fprintf(stream,"*/\n");
fprintf(stream,"/* *** End of %s *** */\n",name);
} /* end write_v_footer */
void write_ctds_header(FILE *stream, char *name)
{
struct tm *tblock;
time_t timer;
char time_str[80];
timer=time(NULL);
tblock = localtime(&timer);
strcpy(time_str,asctime(tblock));
fprintf(stream,"; Lissajous figure CTDS datafile %s\n", name);
fprintf(stream,"; Generated on %s", time_str);
fprintf(stream,"; with LISSAJOU Ver %s\n",VERSION);
fprintf(stream,"; by Aaron C. Caba and Dan Farmer\n");
fprintf(stream,";\n");
fprintf(stream,"; X Y Z R\n");
} /* end write_ctds_header */
void write_ctds_footer(FILE *stream, char *name,
char *data[], struct max_vals val)
{
fprintf(stream,";\n");
fprintf(stream,";\n");
write_stats(stream, ";", data, val, atof(data[SPH_RADIUS]));
fprintf(stream,";\n");
fprintf(stream,"; *** End of %s *** ",name);
} /* end write_ctds_footer */
char *input_name(char *ext)
{
char msg[30], name[13]="";
extern struct field_struct field[];
/* have user input the name of the data file to use */
sprintf(msg,"Name of output file: [%s]",ext);
disp_text(9,field[FILE_NAME].y,msg,EGA_DARKGRAY);
parm_field=FALSE;
if ((fieldinput(FILE_NAME,name,"Press <ESC> to cancel",0) == '\x1B') || (!strcmp(name,"")))
return("");
strupr(name);
strcat(name,ext);
return(name);
} /* end input_name */
void write_stats(FILE *stream, char *prefix,
char *data[], struct max_vals val, float r)
{
fprintf(stream,"%s Parameters used for this generation:\n",prefix);
fprintf(stream,"%s R1 = %s A = %s B = %s\n",prefix,data[MAIN_RADIUS],data[A],data[B]);
fprintf(stream,"%s X-Exponent = %s\n",prefix,data[EXPONENT_X]);
fprintf(stream,"%s Y-Exponent = %s\n",prefix,data[EXPONENT_Y]);
fprintf(stream,"%s Z-Exponent = %s\n",prefix,data[EXPONENT_Z]);
fprintf(stream,"%s Sphere Radius = %s\n",prefix,data[SPH_RADIUS]);
fprintf(stream,"%s Number of Spheres generated: %s\n",prefix,data[SPHERES]);
fprintf(stream,"%s Axis = %s\n",prefix,data[AXIS]);
fprintf(stream,"%s Algorithm = #%s\n",prefix,data[ALGO]);
fprintf(stream,"%s\n",prefix);
fprintf(stream,"%s Minimum X = %f Maximum X = %f\n", prefix, val.xl, val.xh);
fprintf(stream,"%s Minimum Y = %f Maximum Y = %f\n", prefix, val.yl, val.yh);
fprintf(stream,"%s Minimum Z = %f Maximum Z = %f\n", prefix, val.zl, val.zh);
fprintf(stream,"%s\n",prefix);
fprintf(stream,"%s Min/Max XYZs with RADIUS figured in:\n",prefix);
fprintf(stream,"%s Leftmost Point = %f Rightmost Point = %f\n", prefix, val.xl-r, val.xh+r);
fprintf(stream,"%s Lowest Point = %f Highest Point = %f\n", prefix, val.yl-r, val.yh+r);
fprintf(stream,"%s Nearest Point = %f Farthest Point = %f\n", prefix, val.zl-r, val.zh+r);
} /* end write_stats */
/* end-of-file output.c */